package org.smart4j.framework.common.helper;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.smart4j.framework.common.annotation.Action;
import org.smart4j.framework.common.bean.Handler;
import org.smart4j.framework.common.bean.Request;
import org.smart4j.framework.common.util.AnnotationUtil;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 控制器助手类
 *
 * @author YooLin1c
 * @version 1.0.0
 * @since 2018-01-30 18:38
 */
public class ControllerHelper {
    private static final Map<Request, Handler> ACTION_MAP;

    static {
        ACTION_MAP = new HashMap<>();
        //获取所有控制层的类集合
        Set<Class<?>> controllerClassSet = ClassHelper.getControllerClassSet();
        if (CollectionUtils.isNotEmpty(controllerClassSet)) {
            for (Class<?> controllerClass : controllerClassSet) {
                Method[] methods = controllerClass.getDeclaredMethods();
                if (ArrayUtils.isNotEmpty(methods)) {
                    //遍历过滤被@Action注解的方法
                    Arrays.stream(methods).filter(AnnotationUtil::isActionAnnotated).forEach(method -> {
                        //获取@Action注解的value值
                        Action action = method.getAnnotation(Action.class);
                        String mapping = action.value();
                        //校验value格式
                        if (!mapping.matches("\\w+:/\\w*")) {
                            throw new RuntimeException("illegal @Action pattern with : ".concat(mapping).concat("! The right example is get:/user/list"));
                        }
                        //按照指定格式获取请求方式以及请求路径
                        String[] array = mapping.split(":");
                        if (ArrayUtils.isNotEmpty(array)) {
                            if (array.length != 2) {
                                throw new RuntimeException("illegal @Action value with : ".concat(mapping).concat("! The wrong length is ".concat(String.valueOf(array.length))));
                            }
                            String requestMethodName = array[0].toLowerCase();
                            String requestPath = array[1];
                            //封装请求（请求方式+请求路径）
                            Request request = new Request(requestMethodName, requestPath);
                            //封装处理类（控制器类+处理方法）
                            Handler handler = new Handler(controllerClass, method);
                            //保存请求与处理类的关系映射
                            ACTION_MAP.put(request, handler);
                        }
                    });
                }
            }
        }
    }

    /**
     * 根据请求方式以及请求路径获取相应处理类
     *
     * @param requestMethodName 请求方式
     * @param requestPath       请求路径
     * @return 处理类
     */
    public static Handler getHandler(String requestMethodName, String requestPath) {
        Request request = new Request(requestMethodName, requestPath);
        if (!ACTION_MAP.containsKey(request)) {
            throw new RuntimeException("couldn't found mapping handler with request ".concat(request.toString()));
        }
        return ACTION_MAP.get(request);
    }
}
